<?php
namespace Buu\Modules\Eolinker\Apis;

/**
 * User: @lose
 * Date: 2021/11/16
 * Time: 3:10 下午
 */

use Doraemon\tools\Log;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Overtrue\Pinyin\Pinyin;
use Buu\Modules\Eolinker\Models\AmsApi as mAmsApi;
use Buu\Modules\Eolinker\Models\AmsApiTag as mAmsApiTag;
use Doraemon\service\DingTalkAlert;

class Check extends Controller
{
    const SPACE_ID = 'J6SbQyB46eb9f7e7f88605c64b3f7bfb0cc06cfa31afc3f';
    const HOOK_PRODUCT = 'api_management';
    const HOOK_EVENT = 'api_document';
    const HOOK_OPERATION = [
        'add_api_document', // 添加文档
        'update_api_document', // 修改文档
        'delete_api_document', // 删除文档
        'switch_api_status', // 切换状态
        'switch_api_document_version', // 切换api版本
    ];

    const PROJECT_LIST = [
        'yapi',
        'tapi',
        'eapi',
        'bapi',
        'dapi',
        'japi',
        'Bigdata',
    ];

    public function index(Request $request)
    {
        Log::debug('Eolinker创建/修改接口的回调信息', $request->all());
        $spaceId = $request->input('space_id', self::SPACE_ID);
        $product = $request->input('hook_product', self::HOOK_PRODUCT);
        $event = $request->input('hook_event', self::HOOK_EVENT);
        if ($spaceId != self::SPACE_ID || $product != self::HOOK_PRODUCT || $event != self::HOOK_EVENT) {
           return 'ok';
        }

        $content = $request->input('content');
        parse_str(parse_url(parse_url($content['url'], PHP_URL_FRAGMENT), PHP_URL_QUERY), $urlParams);
        if(!in_array($urlParams['projectName'], self::PROJECT_LIST)) {
            return 'ok';
        }

        $operation = $request->input('hook_operation', 'update_api_document');
        if (in_array($operation, self::HOOK_OPERATION)) {
            $stack = explode('_', $operation);
            $firstWord = array_shift($stack);
            $wordList = array_map(function ($word) {
                return ucfirst($word);
            }, $stack);
            $functionName = $firstWord . implode('', $wordList);
            if (method_exists(__CLASS__, $functionName)) {
                $this->$functionName($request, $urlParams);
            }
        }

        return 'ok';
    }

    private function updateApiDocument(Request $request, $urlParams)
    {
        $content = $request->input('content');
        $operator = $this->conversion($content['operator']);
        $warning = $this->checkApiUri($content['api_uri']);
        $warning .= $this->checkInfo($urlParams['apiID']);

        if ($warning) {
            $warning = "接口名称:{$content['api_name']}\n" . $warning;
            $warning .= "接口地址为: {$content['url']}\n";
            $warning .= "辛苦 「{$content['operator']}」 抽时间修改一下";
        } else {
            $warning = "接口文档完全正确，给「{$content['operator']}」打call";
        }
        DingTalkAlert::sendTextMsg(DingTalkAlert::EOLINKER, $warning, false, [$operator]);
    }

    private function addApiDocument(Request $request, $urlParams)
    {
        $this->updateApiDocument($request, $urlParams);
    }

    private function deleteApiDocument(Request $request, $urlParams)
    {
        return true;
    }

    private function switchApiStatus(Request $request, $urlParams)
    {
        return true;
    }

    private function checkInfo($apiId)
    {
        $warning = '';
        $apiTag = mAmsApiTag::getApiTagInfo($apiId);
        if (!$apiTag) {
            $warning .= "请完善接口标签\n";
        }

        $apiInfo = mAmsApi::getApiInfo($apiId);
        if (!$apiInfo['apiManagerID']) {
            $warning .= "请补充接口负责人\n";
        }

        if (!$apiInfo['apiSuccessMock']) {
            $warning .= "请补充接口成功案例\n";
        }

        return $warning;
    }

    private function checkApiUri($apiUri)
    {
        $warning = "";
        if (strpos($apiUri, '/') !== 0) {
            $warning .= "接口路径得以/为前缀,请修改\n";
        }

        if (preg_match('/\\d+/',$apiUri,$res)) {
            $warning .= "接口路径尽可能不包含数字,建议修改\n";
        }

        $stack = array_filter(explode('/', $apiUri));
        if ($stack) {
            foreach ($stack as $word) {
                if ($word != ucfirst($word)) {
                    $warning .= "接口路径需遵守大驼峰命名规范,请修改\n";
                    break;
                }
            }
        }
        return $warning;
    }

    private function conversion($operator)
    {
        $pinyin = new Pinyin();
        if (preg_match("/^[\x{4e00}-\x{9fa5}A-Za-z]+$/u", $operator)) {
            $operator = $pinyin->name($operator);
            $operator = implode('', $operator);
        }
        return $operator;
    }
}